#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include "ohos_init.h"
#include "ohos_types.h"
#include "cmsis_os2.h"
#include "wifi_hotspot.h"
#include "wifi_error_code.h"
#include "lwip/netifapi.h"

#define DEF_TIMEOUT 30
#define AP_SSID "OpenHarmony" // 此处为热点的 SSID（不超过 32 个字符）
#define AP_PASSWORD "1234567890" // 此处为热点的密码（需大于等于 8 个字符）

static struct netif *g_lwip_netif = NULL;
static int g_apEnableSuccess = 0;
static int g_joinedStations = 0;

static void PrintStationInfo(StationInfo* info)
{
    if (!info) return;
    static char macAddress[32] = {0};
    unsigned char* mac = info->macAddress;
    snprintf_s(macAddress, sizeof(macAddress), sizeof(macAddress) - 1, "%02X:%02X:%02X:%02X:%02X:%02X",
        mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
    printf("mac=%s, reason=%d\n", macAddress, info->disconnectedReason);
}

static void OnHotspotStateChangedHandler(int state)
{
    if (state == WIFI_HOTSPOT_ACTIVE)
    {
        g_apEnableSuccess = 1;
        printf("Wifi hotspot active\n");
    }
    else
    {
        g_apEnableSuccess = 0;
        printf("Wifi hotspot inactive\n");
    }
}

static void OnHotspotStaJoinHandler(StationInfo* info)
{
    g_joinedStations++;
    printf("+OnHotspotStaJoin: ");
    PrintStationInfo(info);
    printf("Active stations: %d\n", g_joinedStations);
}

static void OnHotspotStaLeaveHandler(StationInfo* info)
{
    g_joinedStations--;
    printf("-OnHotspotStaLeave: ");
    PrintStationInfo(info);
    printf("Active stations: %d\n", g_joinedStations);
}

static WifiEvent g_eventListener =
{
    .OnHotspotStateChanged = OnHotspotStateChangedHandler,
    .OnHotspotStaJoin = OnHotspotStaJoinHandler,
    .OnHotspotStaLeave = OnHotspotStaLeaveHandler
};

static void WifiAPTask(void)
{
    WifiErrorCode error;
    HotspotConfig config = {0};
    // 注册 Wi-Fi 回调
    if (RegisterWifiEvent(&g_eventListener) != WIFI_SUCCESS)
    {
        printf("Register wifi event failed\n");
        return;
    }
    // 配置热点信息
    strcpy_s(config.ssid, sizeof(config.ssid), AP_SSID);
    strcpy_s(config.preSharedKey, sizeof(config.preSharedKey), AP_PASSWORD);
    config.securityType = WIFI_SEC_TYPE_PSK;
    config.band = HOTSPOT_BAND_TYPE_2G;
    config.channelNum = 7;
    if (SetHotspotConfig(&config) != WIFI_SUCCESS)
    {
        printf("SetHotspotConfig failed\n");
        return;
    }
    // 启动热点
    g_apEnableSuccess = 0;
    if (EnableHotspot() != WIFI_SUCCESS)
    {
        printf("EnableHotspot failed\n");
        return;
    }
    // 检查热点是否使能
    if (IsHotspotActive() == WIFI_HOTSPOT_NOT_ACTIVE)
    {
        printf("Wifi station is not actived\n");
        return;
    }
    while (!g_apEnableSuccess)
    {
        osDelay(100);
    }
    printf("Hotspot started successfully\n");
    // 启动 DHCP 服务器
    g_lwip_netif = netifapi_netif_find("ap0");
    if (g_lwip_netif)
    {
        ip4_addr_t gateway;
        ip4_addr_t ipaddr;
        ip4_addr_t netmask;
        IP4_ADDR(&gateway, 192, 168, 1, 1);   /* 网关地址，例如：192.168.1.1 */
        IP4_ADDR(&ipaddr,  192, 168, 1, 1);   /* 设备 IP 地址，例如：192.168.1.1 */
        IP4_ADDR(&netmask, 255, 255, 255, 0); /* 子网掩码，例如：255.255.255.0 */
        err_t ret = netifapi_netif_set_addr(g_lwip_netif, &ipaddr, &netmask, &gateway);
        if (ret != ERR_OK)
        {
            printf("netifapi_netif_set_addr failed, error: %d\n", ret);
            return;
        }
        netifapi_dhcps_stop(g_lwip_netif); // 默认启动 DHCP 服务器，所以需要先停止
        ret = netifapi_dhcps_start(g_lwip_netif, NULL, 0);
        if (ret != ERR_OK)
        {
            printf("netifapi_dhcps_start failed, error: %d\n", ret);
            return;
        }
        printf("DHCP server started!\n");
    }
}

void WIFIAPDemo(void)
{
    osThreadAttr_t attr;
    attr.name = "WIFIAPDemo";
    attr.attr_bits = 0U;
    attr.cb_mem = NULL;
    attr.cb_size = 0U;
    attr.stack_mem = NULL;
    attr.stack_size = 8192; // 注意此处需要为任务分配更大的栈空间，否则会溢出
    attr.priority = osPriorityNormal;
    if (osThreadNew((osThreadFunc_t) WifiAPTask, NULL, &attr) == NULL)
    {
        printf("Failed to create WifiAPTask!\n");
    }
}

SYS_RUN(WIFIAPDemo);
